import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import os
import cv2
import glob
import pickle
from moviepy.editor import VideoFileClip
from IPython.display import HTML
%matplotlib inline
from Calibration import Calibration
nx = 9
ny = 6
image_path = glob.glob('camera_cal/calibration*.jpg')
calibration = Calibration(nx=nx, ny=ny, image_paths=image_path)
for fname in image_path:
_ = calibration.plot_images(fname)
undist_images = []
images = glob.glob('./test_images/*.jpg')
for fname in images:
undist_img = calibration.plot_images(fname)
undist_images.append(undist_img)
from Warp import PerspectiveTransform
xlen, ylen, _ = undist_images[0].shape
src_pts = np.array([[275, 650],
[1200,650],
[750, 450],
[550, 450]], np.float32)
dts_pts = np.array([[0, ylen],
[xlen, ylen],
[xlen, 0],
[0, 0]], np.float32)
for point in src_pts:
plt.imshow(undist_images[0])
plt.plot(point[0], point[1], 'o', color='r')
plt.show()
perspective = PerspectiveTransform(src_pts, dts_pts)
warp_images = [perspective.warp(img) for img in undist_images]
fig = plt.figure(figsize=(12,18))
for i, img in enumerate(warp_images):
ax = plt.subplot(2,4,i+1)
ax.imshow(img, cmap='gray')
plt.subplots_adjust(left=0., right=1, top=0.5, bottom=0.)
from Thresholding import *
binary_images = [combined_thresholds(img) for img in warp_images]
fig = plt.figure(figsize=(12,18))
for i, img in enumerate(binary_images):
ax = plt.subplot(2,4,i+1)
ax.imshow(img, cmap='gray')
plt.subplots_adjust(left=0.0, right=1, top=0.5, bottom=0.0)
from LaneDetectors import *
lane_detector = LaneDetector(primary = True, n_windows = 9, margin = 100)
lane_images = [lane_detector.detect_lanes(image, img_only=True) for image in binary_images]
fig = plt.figure(figsize=(18,40))
for i, img in enumerate(lane_images):
ax = plt.subplot(3, 3,i+1)
ax.imshow(img, cmap='gray')
plt.subplots_adjust(left=0.0, right=1, top=0.5, bottom=0.0)
lane_detector = LaneDetector(primary = False, n_windows = 10, margin = 100)
def lane_overlay(binary_image, left_fit, right_fit):
""" Get the lane overlay, showing the detected lane
Args:
binary_image: The image on which the lane lines are to be detected. Note that all pre-processing
should have been applied to the image prior to this step. The image must be binary, and
contain only values in {0, 1}.
left_fit: Polynomial fit to the left lane line
right_fit: Polynomial fit to the right lane line
Returns:
Green overlay, do be drawn on a calibrated color image, showing detected lane line
between left_fit and right_fit.
"""
## The lane is represented as an overlay between the two lane lines, which
## are taken to be the polynomials defined by left_fit and right_fit.
plot_y = np.linspace(0, binary_image.shape[0]-1, binary_image.shape[0])
left_fit_x = eval_poly(plot_y, left_fit)
right_fit_x = eval_poly(plot_y, right_fit)
left_points = np.array([np.transpose(np.vstack([left_fit_x, plot_y]))])
right_points = np.array([np.flipud(np.transpose(np.vstack([right_fit_x, plot_y])))])
points = np.hstack((left_points, right_points))
return_image = np.zeros((1280, 720, 3), dtype=np.uint8)
cv2.fillPoly(return_image, np.int_([points]), (0, 255, 0))
return return_image
from math import log2
# The calibrator, perspective transform etc. are defined earlier in the notebook. We apply the same defaults here.
class CurvatureCollector:
def __init__(self):
self.left_curvatures = []
self.right_curvatures = []
self.deviations = []
curvature_accumulator = CurvatureCollector()
def build_processor(calibrator=calibration, warper=perspective, detector=lane_detector , curv_acc=curvature_accumulator, overlay=False):
def processor(image):
image_undistorted = calibration.undistort(image)
image_working = perspective.warp(image_undistorted)
binary_images = combined_thresholds(image_working)
left_fit, left_curvature, right_fit, right_curvature, deviation, output_image = detector.detect_lanes(binary_images)
curv_acc.left_curvatures.append(left_curvature)
curv_acc.right_curvatures.append(right_curvature)
curv_acc.deviations.append(deviation)
if overlay:
overlay_image = lane_overlay(output_image, left_fit, right_fit)
overlay_image = perspective.unwarp(overlay_image)
output_image = cv2.addWeighted(image_undistorted, 1, overlay_image, 0.3, 0)
curvature_text = "Radius of Curvature: {:.2f} m".format(0.5*(left_curvature + right_curvature))
cv2.putText(output_image, curvature_text, (30, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 4, cv2.LINE_AA)
deviation_text = "Offset: {:.2f} m".format(deviation)
cv2.putText(output_image, deviation_text, (30, 180), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 4, cv2.LINE_AA)
return output_image
return processor
video0_output = 'project_video_final.mp4'
processor = build_processor(overlay=True)
video0 = VideoFileClip("project_video.mp4")
video0_processed = video0.fl_image(processor)
%time video0_processed.write_videofile(video0_output, audio=False)
video0_output = 'harder_challenge_video_final.mp4'
processor = build_processor(overlay=True)
video0 = VideoFileClip("harder_challenge_video.mp4")
video0_processed = video0.fl_image(processor)
%time video0_processed.write_videofile(video0_output, audio=False)